<?




Cache::init();



class Cache {


	// кеш для резльутатом фукций 
	static $Cache=array();
	
	static function init()
	{
		Cache::$call = new Cache();
	} 
	private function __construct() {}
	
	
	
	// Cache::$call - объект для вызова через кеш любых функций
	// Пример: Cache::$call->file_exists($file);
	// функция func_name должна существовать. результаты вызова сохраняются в кеш-памяти для данного набора аргументов
	static $call=null;
	
	// магический метод __call используется для вызова любых функций через кеширующий объект Cache::$call
	public function __call($func, $args)
	{
		/**/ 
		if (!function_exists($func))
		{
			triger_error("Undefined function '$func' called by Cache::$call object", E_USER_ERROR);
			return null;
		} 
		/**/
				
		$str_args = serialize($args);
		
		$key = $func.'::'. $str_args;
			if(strlen($key)>300) 
				$key = substr($key,0,300).'...['.md5($str_args).']';
		
		if (isset(self::$Cache[$key])) 
			return self::$Cache[$key];
		else 
			return (self::$Cache[$key] = 
						call_user_func_array($func, $args)
						);
			
	}
	
	
	// отправляет HTTP-заголвоки для запрета кеширования старницы
	static function nocache_headers()
	{
		// HTTP/1.1
		Header("Cache-Control: no-cache, must-revalidate");  
		// HTTP/1.0 
		Header("Pragma: no-cache"); 
		//Дата в прошлом
		Header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
		// документ всегда новый
		Header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT");
	}
	
	// выводит мета-теги для щзапрета кеширования страницы
	static function nocache_html($do_return=false)
	{
		// Запрет на кэширование вообще (документ не будет кэшироваться ни proxy-сервером, ни браузером):
		$html = '<meta http-equiv="Cache-Control" content="no-cache">'; 
		
		
 


		if ($do_return) return $html;
		else echo $html;
	}
	
	
	static function cache_control()
	{
		// HTML:
		
		// Документ будет кэшироваться браузером, но не будет кэшироваться proxy-сервером
		//<meta http-equiv="Cache-Control" content="private"> 
		
		//Документ будет кэшироваться, даже если и не должен, вроде бы, при обычных обстоятельствах.
		// <meta http-equiv="Cache-Control" content="public"> 
		
		//Документ кэшируется, но не сохраняется в архиве.
		//<meta http-equiv="Cache-Control" content="no-store"> 
		
		// Можно прямо сказать браузеру: "Обнови-ка мне эту страницу". (В параметре max-age указано, на сколько секунд кэшируется документ). Может быть полезно при использовании PHP для програмного обновления страниц.
		// <meta http-equiv="Cache-Control" content="max-age=3600, must-revalidate"> 
		
		// А можно сказать это только прокси-серверу
		// <meta http-equiv="Cache-Control" content="max-age=3600, proxy-revalidate"> 
		
		// headers : http://www.codenet.ru/webmast/php/caching.php
	
	}
	
}


/*** Снижение нагрузки на сервер, через правильную отдачу заголвоков для статичных файлов *** 

To reduce the burden on the server, you might want to output "Etag" and/or "Last-Modified" on http response header.  But there are some headers, which PHP itself outputs automatically, disturbing this.  So I wrote this function with erasing these.

If you guys know how to judge the return values of function "stat", in order to avoid using "is_file" or "is_readable" (or "is_dir"), please let me know or just write it here.

If you don't have to do anything special on 404, "header('HTTP/1.x xxx xxxxx');" can be inside of the function.

<?php

$filename = '/foo/bar/myfeed.rss';
$http_stat_code = readfile_if_modified($filename, array('Content-Type: text/xml'));
switch($http_stat_code) {
case 404:
    header('HTTP/1.0 404 Not Found');
    echo '<html><head></head><body><a href="http://example.com/">http://example.com/<a></body></html>';
    exit;
default:
    header('X-System-Url: http://example.com/', true, $http_stat_code);
}

function readfile_if_modified($filename, $http_header_additionals = array()) {

    if(!is_file($filename)) {
//      header('HTTP/1.0 404 Not Found');
        return 404;
    }

    if(!is_readable($filename)) {
//      header('HTTP/1.0 403 Forbidden');
        return 403;
    }

    $stat = @stat($filename);
    $etag = sprintf('%x-%x-%x', $stat['ino'], $stat['size'], $stat['mtime'] * 1000000);

    header('Expires: ');
    header('Cache-Control: ');
    header('Pragma: ');

    if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
        header('Etag: "' . $etag . '"');
//      header('HTTP/1.0 304 Not Modified');
        return 304;
    } elseif(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $stat['mtime']) {
        header('Last-Modified: ' . date('r', $stat['mtime']));
//      header('HTTP/1.0 304 Not Modified');
        return 304;
    }

    header('Last-Modified: ' . date('r', $stat['mtime']));
    header('Etag: "' . $etag . '"');
    header('Accept-Ranges: bytes');
    header('Content-Length:' . $stat['size']);
    foreach($http_header_additionals as $header) {
        header($header);
    }

    if(@readfile($filename) === false) {
//      header('HTTP/1.0 500 Internal Server Error');
        return 500;
    } else {
//      header('HTTP/1.0 200 OK');
        return 200;
    }

}

***/






/*** Включение сжатия страниц!

1) в файле .htaccess добавьте:

php_flag zlib.output_compression On

2) в общем верхнем скрипте сайта (в котором обычно описывается шапка сайта, например header.php)
вставте в самое начало скрипта

	Если библиотека zlib подключена, то дописываем в файл темы wordpress (в header.php в самом начале) код:

	<?php
	ini_set(’zlib.output_compression’, ‘On’);
	ini_set(’zlib.output_compression_level’, ‘1′);
	?>


if(!ini_get('zlib.output_compression')) ob_start("ob_gzhandler"); 

// а это - если система сжимает но не выдает заголвока gzip 
if((ini_get('zlib.output_compression'))&&(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],"gzip")!==FALSE))
{
         Header("Content-Encoding: gzip\n");
 
}


Это позволит проверять включено или нет сжатие средствами ВЕБ-сервера (zlib.output_compression) и, если оно не включено, задействовать альтернативный метод сжатия страниц с помощью функции ob_start("ob_gzhandler").

Важная информация!
You cannot use both ob_gzhandler() and zlib.output_compression. Also note that using  zlib.output_compression is preferred over ob_gzhandler(). 
Вы не можете использовать ob_gzhandler() и zlib.output_compression одновременно! И использование zlib.output_compression лучше, чем использование ob_gzhandler().
Именно поэтому мы сначала пытаемся задействовать zlib.output_compression, а уж потом, если оно не включилось - задействуем ob_gzhandler().


***/